/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.demo.codegen;

import com.querydsl.codegen.utils.model.SimpleType;
import com.querydsl.codegen.utils.model.TypeCategory;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.DerbyTemplates;
import com.querydsl.sql.SQLTemplates;
import net.apexes.codegen.core.BasicNamingStrategy;
import net.apexes.codegen.core.EntityModel;
import net.apexes.codegen.core.OrmliteEntityBeanSerializer;
import net.apexes.codegen.core.OrmliteExporter;
import net.apexes.codegen.core.SuperType;
import net.apexes.commons.lang.Resources;
import net.apexes.commons.querydsl.support.QuerydslEnumeSupport;
import net.apexes.demo.codegen.enume.support.DemoEnumeSupport;
import net.apexes.demo.codegen.entity.base.OrmliteEntityBase;
import net.apexes.demo.codegen.util.DemoDatabases;

import java.io.File;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 *
 */
public class DemoOrmliteAnnotationCodegen {
    
    /**
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        try (Connection conn = DemoDatabases.createConnection()) {
            List<String> tables = findTables(conn);
            codegen(DerbyTemplates.builder().build(), conn, tables);
        }
        System.out.println("Codegen Over!");
    }

    private static final String PACKAGE = "net.apexes.demo.codegen.ormlite.annotation.entity";
    private static final String TARGET = "apexes-codegen-demo-query/src/main/java";

    private static List<String> findTables(Connection conn) throws Exception {
        List<String> tables = new ArrayList<>();
        DatabaseMetaData md = conn.getMetaData();
        try (ResultSet rs = md.getTables(null, "PUBLIC", null, new String[]{"TABLE"})) {
            while (rs.next()) {
                String tableName = rs.getString("TABLE_NAME");
                tables.add(tableName);
            }
            return tables;
        }
    }

    private static void codegen(SQLTemplates templates, Connection conn, List<String> tables) throws Exception {
        Configuration config = DemoEnumeSupport.getInstance().register(QuerydslEnumeSupport.utilDateConfiguration(templates), tables);

        final SuperType supertype = createSupertype(OrmliteEntityBase.class);

        OrmliteEntityBeanSerializer beanSerializer = new OrmliteEntityBeanSerializer("");
        beanSerializer.setAddToString(true);
        BasicNamingStrategy namingStrategy = new BasicNamingStrategy();
        namingStrategy.setDefaultVarName("$");
        
        OrmliteExporter exporter = new OrmliteExporter() {
            
            @Override
            protected EntityModel finishEntityModel(EntityModel model) {
                model.setSupertype(supertype);
                //model.addInterface(iface);
                return model;
            }
        };

        String projectPath = Resources.getProjectPath(DemoOrmliteColumnCodegen.class);
        File file = new File(projectPath);
        while (!"apexes-codegen".equals(file.getName())) {
            file = file.getParentFile();
        }

        File targetFolder = new File(file, TARGET);

        exporter.setConfiguration(config);
        exporter.setSchemaPattern("PUBLIC");
        exporter.setSerializer(beanSerializer);
        exporter.setTargetFolder(targetFolder);
        exporter.setPackageName(PACKAGE);
        exporter.setNamingStrategy(namingStrategy);
        exporter.export(conn.getMetaData());
    }
    
    private static SuperType createSupertype(Class<?> entityClass) {
        SimpleType type = new SimpleType(TypeCategory.ENTITY,
                entityClass.getName(),
                entityClass.getPackage().getName(),
                entityClass.getSimpleName(), false, false);
        return new SuperType(type);
    }

}
